import { v4 as uuidv4 } from 'uuid';
import { MCPMessage } from '../../api/types/index.js';
import { MessageRepository } from '../../mongodb/repositories/MessageRepository.js';
import { TaskSessionService } from '../../mongodb/services/TaskSessionService.js';
import { IMessage, ITaskSession, TaskSessionCreationData } from '../../mongodb/models/types/index.js';
import { HydratedDocument } from 'mongoose';

/**
 * 消息处理结果
 */
export interface MessageProcessingResult {
  messageId: string;
  status: 'processed' | 'failed' | 'queued';
  processingTime: number;
  error?: string;
  sessionId?: string;
}

/**
 * 消息处理选项
 */
export interface MessageProcessingOptions {
  storeInDatabase?: boolean;
  createSession?: boolean;
  processAsync?: boolean;
  maxRetries?: number;
}

/**
 * MCP消息处理服务
 * 负责消息的接收、验证、存储和分发
 */
export class MessageProcessingService {
  private messageRepository: MessageRepository;
  private taskSessionService: TaskSessionService;

  constructor(
    messageRepository: MessageRepository,
    taskSessionService: TaskSessionService
  ) {
    this.messageRepository = messageRepository;
    this.taskSessionService = taskSessionService;
  }

  /**
   * 处理单个消息
   */
  async processMessage(
    message: MCPMessage,
    options: MessageProcessingOptions = {}
  ): Promise<MessageProcessingResult> {
    const startTime = Date.now();
    let sessionId: string | undefined;

    try {
      console.log(`开始处理消息 ${message.id}, 类型: ${message.type}`);

      // 默认选项
      const opts = {
        storeInDatabase: true,
        createSession: false,
        processAsync: false,
        maxRetries: 3,
        ...options
      };

      // 创建会话（如果需要）
      if (opts.createSession) {
        sessionId = await this.createSessionForMessage(message);
      }



      // 根据消息类型进行特定处理
      await this.processMessageByType(message, sessionId);

      const processingTime = Date.now() - startTime;
      console.log(`消息 ${message.id} 处理完成，耗时 ${processingTime}ms`);

      // 在处理完成后存储消息
      if (opts.storeInDatabase) {
        try {
          await this.storeMessage(message, 'processed', processingTime, sessionId);
        } catch (dbError) {
          const message = dbError instanceof Error ? dbError.message : 'Unknown DB error';
          console.warn(`数据库存储失败: ${message}`);
        }
      }

      return {
        messageId: message.id,
        status: 'processed',
        processingTime,
        sessionId
      };

    } catch (error) {
      const processingTime = Date.now() - startTime;
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      console.error(`消息 ${message.id} 处理失败:`, error);

      // 存储失败状态的消息
      if (options.storeInDatabase) {
        try {
          await this.storeMessage(message, 'failed', processingTime, sessionId);
        } catch (dbError) {
          const message = dbError instanceof Error ? dbError.message : 'Unknown DB error';
          console.warn(`存储失败消息时出错: ${message}`);
        }
      }

      // 如果启用了重试机制
      if (message.retryCount < (options.maxRetries || 3)) {
        await this.scheduleRetry(message, options);
        return {
          messageId: message.id,
          status: 'queued',
          processingTime,
          error: `Scheduled for retry (attempt ${message.retryCount + 1})`
        };
      }

      return {
        messageId: message.id,
        status: 'failed',
        processingTime,
        error: errorMessage
      };
    }
  }

  /**
   * 批量处理消息
   */
  async processBatchMessages(
    messages: MCPMessage[],
    options: MessageProcessingOptions = {}
  ): Promise<MessageProcessingResult[]> {
    const results: MessageProcessingResult[] = [];
    
    // 根据是否异步处理选择执行策略
    if (options.processAsync) {
      // 并发处理
      const promises = messages.map(message => 
        this.processMessage(message, options).catch(error => ({
          messageId: message.id,
          status: 'failed' as const,
          processingTime: 0,
          error: error instanceof Error ? error.message : String(error)
        }))
      );
      
      results.push(...await Promise.all(promises));
    } else {
      // 顺序处理
      for (const message of messages) {
        const result = await this.processMessage(message, options);
        results.push(result);
      }
    }

    return results;
  }

  /**
   * 根据消息类型进行特定处理
   */
  private async processMessageByType(message: MCPMessage, sessionId?: string): Promise<void> {
    const { type } = message;

    switch (type) {
      case 'user.message':
        await this.processUserMessage(message, sessionId);
        break;
      case 'system.notification':
        await this.processSystemNotification(message);
        break;
      case 'ai.request':
        await this.processAIRequest(message);
        break;
      case 'webhook.callback':
        await this.processWebhookCallback(message);
        break;
      case 'file.upload':
        await this.processFileUpload(message);
        break;
      default:
        console.warn(`未知的消息类型: ${type}, 使用默认处理逻辑`);
        await this.processGenericMessage(message);
    }
  }

  /**
   * 处理用户消息
   */
  private async processUserMessage(message: MCPMessage, sessionId?: string): Promise<void> {
    console.log(`处理用户消息: ${message.id}`);
    
    // 这里可以添加用户消息的特定处理逻辑
    // 例如：情感分析、内容过滤、自动回复等
    
    if (sessionId) {
      // 更新会话的最后活动时间
      // await this.taskSessionService.updateLastActivity(sessionId);
    }
  }

  /**
   * 处理系统通知
   */
  private async processSystemNotification(message: MCPMessage): Promise<void> {
    console.log(`处理系统通知: ${message.id}`);
    
    // 系统通知处理逻辑
    // 例如：发送邮件、推送通知、记录日志等
  }

  /**
   * 处理AI请求
   */
  private async processAIRequest(message: MCPMessage): Promise<void> {
    console.log(`处理AI请求: ${message.id}`);
    
    // AI请求处理逻辑
    // 例如：调用AI服务、处理响应、存储结果等
    
    if (message.payload['requiresResponse']) {
      // 生成AI响应
      await this.generateAIResponse(message);
    }
  }

  /**
   * 处理Webhook回调
   */
  private async processWebhookCallback(message: MCPMessage): Promise<void> {
    console.log(`处理Webhook回调: ${message.id}`);
    
    // Webhook处理逻辑
    // 例如：验证签名、处理事件、触发后续操作等
  }

  /**
   * 处理文件上传
   */
  private async processFileUpload(message: MCPMessage): Promise<void> {
    console.log(`处理文件上传: ${message.id}`);
    
    // 文件上传处理逻辑
    // 例如：病毒扫描、格式转换、存储到云端等
  }

  /**
   * 通用消息处理
   */
  private async processGenericMessage(message: MCPMessage): Promise<void> {
    console.log(`使用通用处理器处理消息: ${message.id}`);
    
    // 通用处理逻辑
    // 例如：记录统计信息、触发规则引擎等
  }

  /**
   * 为消息创建会话
   */
  private async createSessionForMessage(message: MCPMessage): Promise<string> {
    try {
      const sessionData: TaskSessionCreationData = {
        sessionId: uuidv4(),
        userId: message.source || 'system',
        title: `Session for message ${message.type}`,
        description: `Auto-created session for message ${message.id}`,
        status: 'active',
        priority: message.priority === 'critical' ? 'high' : 'medium',
        tags: [message.type, 'auto-created'],
        metadata: {
          createdBy: 'message-processor',
          originalMessageId: message.id,
          messageType: message.type,
          complexity: 'simple',
          subTaskStats: { total: 0, completed: 0, inProgress: 0, pending: 0, cancelled: 0 }
        }
      };

      const session = await this.taskSessionService.createTaskSession(sessionData) as HydratedDocument<ITaskSession>;
      console.log(`为消息 ${message.id} 创建会话 ${session.id}`);

      return session.id;
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Unknown error';
      console.warn(`为消息创建会话失败，使用临时ID: ${message}`);
      return `temp-session-${uuidv4()}`;
    }
  }

  /**
   * 存储消息到数据库
   */
  private async storeMessage(
    message: MCPMessage,
    status: IMessage['status'],
    processingTime: number,
    sessionId?: string
  ): Promise<void> {
    try {
      const messageData = {
        messageId: message.id,
        userId: message.source || 'system',
        sessionId: sessionId,
        role: this.determineMessageRole(message),
        content: this.extractMessageContent(message),
        messageType: message.type,
        metadata: {
          source: message.source,
          priority: message.priority,
          headers: message.headers,
          originalPayload: message.payload,
          ttl: message.ttl,
          maxRetries: message.maxRetries,
          retryCount: message.retryCount
        },
        status,
        processingTime
      };

      await this.messageRepository.create(messageData);
      console.log(`消息 ${message.id} (状态: ${status}) 已存储到数据库`);
    } catch (error) {
      // 这个错误现在由调用者处理，这里只记录
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      console.error(`消息 ${message.id} 存储到数据库失败: ${errorMessage}`);
      throw error;
    }
  }

  /**
   * 确定消息角色
   */
  private determineMessageRole(message: MCPMessage): 'user' | 'assistant' | 'system' | 'tool' {
    if (message.type.startsWith('user.')) return 'user';
    if (message.type.startsWith('ai.') || message.type.startsWith('assistant.')) return 'assistant';
    if (message.type.startsWith('system.')) return 'system';
    if (message.type.startsWith('tool.')) return 'tool';
    return 'system'; // 默认
  }

  /**
   * 提取消息内容
   */
  private extractMessageContent(message: MCPMessage): string {
    if (typeof message.payload['content'] === 'string') {
      return message.payload['content'];
    }

    if (typeof message.payload['text'] === 'string') {
      return message.payload['text'];
    }

    if (typeof message.payload['message'] === 'string') {
      return message.payload['message'];
    }

    return JSON.stringify(message.payload);
  }

  /**
   * 生成AI响应
   */
  private async generateAIResponse(message: MCPMessage): Promise<void> {
    console.log(`为消息 ${message.id} 生成AI响应`);
    
    // 这里应该调用AI服务
    // 目前只是一个占位符
    
    const responseMessage: MCPMessage = {
      id: uuidv4(),
      type: 'ai.response',
      payload: {
        originalMessageId: message.id,
        response: '这是一个自动生成的响应',
        model: 'placeholder-model',
        usage: {
          promptTokens: 0,
          completionTokens: 0,
          totalTokens: 0
        }
      },
      headers: {
        'x-generated-by': 'message-processing-service',
        'x-in-response-to': message.id
      },
      timestamp: new Date().toISOString(),
      source: 'ai-service',
      priority: message.priority,
      retryCount: 0,
      maxRetries: 0
    };

    // 递归处理AI响应消息
    await this.processMessage(responseMessage, {
      storeInDatabase: true,
      createSession: false,
      processAsync: false
    });
  }

  /**
   * 安排重试
   */
  private async scheduleRetry(message: MCPMessage, options: MessageProcessingOptions): Promise<void> {
    const retryMessage: MCPMessage = {
      ...message,
      retryCount: message.retryCount + 1,
      headers: {
        ...message.headers,
        'x-retry-attempt': (message.retryCount + 1).toString(),
        'x-retry-scheduled-at': new Date().toISOString()
      }
    };

    // 计算退避延迟
    const backoffDelay = Math.pow(2, message.retryCount) * 1000; // 指数退避

    console.log(`消息 ${message.id} 安排在 ${backoffDelay}ms 后重试 (第${message.retryCount + 1}次)`);

    // 这里应该将消息放入延迟队列
    // 目前只是记录日志
    setTimeout(async () => {
      await this.processMessage(retryMessage, options);
    }, backoffDelay);
  }
}
